﻿using AutoMapper;
using Azure.Core;
using Microsoft.EntityFrameworkCore;
using Windows.Infrastructure.EFCore.Share.Extensions;
using Windows.Infrastructure.Share.CustomException;
using Windows.Infrastructure.Share.Extensions;
using Windows.Infrastructure.Share.Security;
using Windows.Service.Share;
using Windows.WorkFlow.Domain;
using Windows.WorkFlow.Domain.Enums;
using Windows.WorkFlow.Infrastructure.EFCore;

namespace Windows.WorkFlow.Service
{
    public class FlowInstanceService : IFlowInstanceService
    {
        private readonly IMapper _mapper;
        //private readonly ICache _cache;
        private readonly WorkFlowDbContext _db;
        private readonly ICurrentUser _currentUser;
        private readonly IWorkFlowManager _workFlowManager;
        public FlowInstanceService(IMapper mapper, WorkFlowDbContext db,ICurrentUser currentUser, IWorkFlowManager workFlowManager)
        {
            _mapper = mapper;
            _db = db;
            _currentUser = currentUser;
            _workFlowManager = workFlowManager;
        }
        /// <summary>
        /// 我的流程
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PageResponse<FlowInstanceResponse>> MineFlowInstances(PageRequest<FlowInstanceRequest> request)
        {
            var query = Where(request);
            var list = await query.Where(x => x.CreatedBy == _currentUser.Id).Paging(request.PageIndex, request.PageSize).ToListAsync();
            var response = new PageResponse<FlowInstanceResponse>
            {
                TotalCount = await query.CountAsync(),
                PageIndex = request.PageIndex,
                PageSize = request.PageSize,
                List = _mapper.Map<List<FlowInstanceResponse>>(list)
            };
            return response;
        }
        /// <summary>
        /// 流程实例保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async System.Threading.Tasks.Task Save(FlowInstanceSaveRequest request)
        {
            FlowInstance? model = _mapper.Map<FlowInstance>(request);
            if (request.Id != null)
            {
                model = await _db.FlowInstance.FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("流程实例不存在!");
                model.FlowId = request.FlowId;
            }
            if (request.Id == null)
            {
                await _db.FlowInstance.AddAsync(model);
            }
            await _db.SaveChangesAsync();
            model.Flow = _db.Flow.FindById(request.FlowId);
            FlowRuntime runtime = new(model);
            await _workFlowManager.Start(runtime);
            model.CurrentNodeId = runtime.NextNode.Id;
            model.CurrentNodeName = runtime.NextNode.Properties.Text;
            await _db.SaveChangesAsync();
        }
        private IQueryable<FlowInstance> Where(PageRequest<FlowInstanceRequest> request)
        {
            IQueryable<FlowInstance> query = _db.FlowInstance.Include(x => x.Flow);
            if (!request.Query.Name.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Flow != null && x.Flow.Name.Contains(request.Query.Name!));
            }
            return query;
        }
    }
}
